

#include <iostream>
#include <fstream>
#include "opencv2/opencv.hpp"
#include <opencv/cv.h>
#include <opencv2/highgui.hpp>

#include <opencv2/stitching.hpp>
#include "opencv2/core/ippasync.hpp"


using namespace std;
using namespace cv;

#include<ctime>

bool matIsEqual(const cv::Mat mat1, const cv::Mat mat2) {
    if (mat1.empty() && mat2.empty()) {
        return true;
    }
    if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims||
        mat1.channels()!=mat2.channels()) {
        return false;
    }
    if (mat1.size() != mat2.size() || mat1.channels() != mat2.channels() || mat1.type() != mat2.type()) {
        return false;
    }
    int nrOfElements1 = mat1.total()*mat1.elemSize();
    if (nrOfElements1 != mat2.total()*mat2.elemSize()) return false;
    bool lvRet = memcmp(mat1.data, mat2.data, nrOfElements1) == 0;
    return lvRet;
}
cv::Mat getcvMatrixDotProd(cv::Mat A, cv::Mat B )
{
    B = B.t();
    Mat dst_mat( A.rows,B.rows,CV_32FC1);
    for(int i=0;i< A.rows;i++)
    {
        for(int j=0;j<B.rows;j++)
        {
            dst_mat.at<float>(i,j) = A.rowRange(i, i+1).dot(B.rowRange(j, j+1));
//            cout << "dot at :"<< i <<","<<j<<":" <<  dst_mat.at<float>(i,j) <<endl;
        }
    }
//    cout << "dst mat :" << dst_mat <<endl;
    return dst_mat ;
}
int main(int argc, char** argv)
{


    string useIpp(argv[1]);

    int width = 500, height = 500;
    cv::Mat data;
    cv::Scalar mm, ss;

    // CV_32FC1 uniform distribution
    data.create(height, width, CV_32FC1);
    cv::randu(data, cv::Scalar::all(0.), cv::Scalar::all(1.));
    cv::imshow("data", data);
//    cv::waitKey();


    if("useIpp"==useIpp)
    {
        ipp::setUseIPP(true);
    } else{
        ipp::setUseIPP(false);
    }

    std::cout << "ipp::useIPP();" << ipp::useIPP()<< std::endl;


    clock_t start,finish;


//    cv::Mat mul_dst ;
//    start=clock();
//    for(int i=0;i< 1000;i++)
//    {
//        cv::multiply(data,data,mul_dst);
//    }
//    finish=clock();
//    cout<< "cv multiy 1000 times cost :"<<(finish-start)<<endl;
//
    cv::Mat pro_dst ;
    start=clock();
    for(int i=0;i< 10;i++)
    {
        pro_dst = data* data ;
    }
    finish=clock();
    cout<< "cv *gemm 10 times cost :"<<(finish-start)<<endl;

    cv::Mat pro_dst_1 ;
    start=clock();
    for(int i=0;i< 10;i++)
    {
        pro_dst_1 = getcvMatrixDotProd(data,data);
    }
    finish=clock();
    cout<< "cv *gemm from dot 10 times cost :"<<(finish-start)<<endl;

    cout << "mat equal:" << matIsEqual(pro_dst,pro_dst_1)<<endl;
//    start=clock();
//    for(int i=0;i< 1000;i++)
//    {
//        float dot_val = data.dot(data );
//    }
//    finish=clock();
//    cout<< "cv *dot 1000 times cost :"<<(finish-start)<<endl;
}
